package cn.com.dragonpass.infra.report.utils;

import cn.com.dragonpass.common.utils.ObjectUtils;
import cn.com.dragonpass.infra.report.config.WeaverConfig;
import cn.com.dragonpass.report.dto.WeaverDepartmentDto;
import cn.com.dragonpass.report.dto.WeaverHrmUserInfoWithDto;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.util.*;

/**
 * 推送泛微
 */
@Service
@Slf4j
public class WeaverPushUtil {

    @Autowired
    private WeaverConfig weaverConfig;

    @Autowired
    private RedisService redisService;

    private static final long time = 25 * 60 * 1000;


    /**
     * 泛微审批推送
     *
     * @param map
     * @return
     */
    public Map<String,Object> approvalPush(Map<String, Object> map) {
        return restful(weaverConfig.getApprovalPath(), map);
    }


    /**
     * 获取泛微用户id
     */
    public WeaverHrmUserInfoWithDto getHrmUserInfoWithPage(String workCode, String loginId){
        Map<String, Object> map = new HashMap<>();
        map.put("workcode", workCode);
        map.put("loginid", loginId);
        Map<String, Object> reqMap = new HashMap<>();
        reqMap.put("params", JSONUtil.toJsonStr(map));

        //ECOLOGY返回的token
        String token = redisService.get("SERVER_TOKEN");
        String publicKey = redisService.get("SERVER_PUBLIC_KEY");
        if (StrUtil.isEmpty(token)||StrUtil.isEmpty(publicKey)) {
            token = (String) getToken().get("token");
        }

        Map<String, Object> resData = restfulPush(token, reqMap, weaverConfig.getHrmUserPath());
        if (ObjectUtil.isNotNull(resData.get("msg")) && resData.get("msg").toString().contains("token不存在或者超时")) {
            redisService.delete("SERVER_TOKEN");
            resData = restfulPush((String) getToken().get("token"), reqMap, weaverConfig.getHrmUserPath());
        }

        if ("1".equals(resData.get("code"))){
            JSONObject data = JSONUtil.parseObj(resData.get("data"));
            if (data.getInt("totalSize") != 0) {
                JSONArray dataList = JSONUtil.parseArray(data.get("dataList"));
                return JSONUtil.toBean(JSONUtil.toJsonStr(dataList.get(0)),WeaverHrmUserInfoWithDto.class);
            }
            return null;
        }
        return null;
    }

    /**
     * 获取泛微部门id
     *
     * {
     *     "params":
     *     {
     *         "departmentname":"部门",
     *         "departmentcode":"code1",
     *         "pagesize":20,
     *         "curpage":1
     *     }
     * }
     */
    public WeaverDepartmentDto getWeaverDepartment(String depName, String depCode) {
        Map<String, Object> map = new HashMap<>();
        map.put("departmentname", depName);
        map.put("departmentcode", depCode);
        map.put("pagesize", 99999);
        map.put("curpage", 1);

        Map<String, Object> reqMap = new HashMap<>();
        reqMap.put("params", JSONUtil.toJsonStr(map));

        //ECOLOGY返回的token
        String token = redisService.get("SERVER_TOKEN");
        if (StrUtil.isEmpty(token)) {
            token = (String) getToken().get("token");
        }

        Map<String, Object> resData = restfulPush(token, reqMap, weaverConfig.getDepartmentPath());
        if (ObjectUtil.isNotNull(resData.get("msg")) && resData.get("msg").toString().contains("token不存在或者超时")) {
            redisService.delete("SERVER_TOKEN");
            resData = restfulPush((String) getToken().get("token"), reqMap, weaverConfig.getDepartmentPath());
        }

        if ("1".equals(resData.get("code"))){
            JSONObject data = JSONUtil.parseObj(resData.get("data"));
            if (data.getInt("totalSize") != 0) {
                JSONArray dataList = JSONUtil.parseArray(data.get("dataList"));
               return JSONUtil.toBean(JSONUtil.toJsonStr(dataList.get(0)),WeaverDepartmentDto.class);
            }
            return null;
        }
        return null;
    }

    /**
     * 第三步：
     *
     * 调用ecology系统的rest接口，请求头部带上token和用户标识认证信息
     *
     * @param map 请求参数json串
     *
     * 注意：ECOLOGY系统所有POST接口调用请求头请设置 "Content-Type","application/x-www-form-urlencoded; charset=utf-8"
     */
    private Map<String, Object> restful(String apiPath, Map<String, Object> map) {
        //ECOLOGY返回的token
        String token = redisService.get("SERVER_TOKEN");
        if (StrUtil.isEmpty(token)) {
            token = (String) getToken().get("token");
        }

        Map<String, Object> resData = restfulPush(token, map, apiPath);
        if (ObjectUtil.isNotNull(resData.get("msg")) && resData.get("msg").toString().contains("token不存在或者超时")) {
            redisService.delete("SERVER_TOKEN");
            resData = restfulPush((String) getToken().get("token"), map, apiPath);
        }
        return resData;
    }

    private Map<String, Object> restfulPush(String token, Map<String, Object> map, String apiPath) {
        String spk = redisService.get("SERVER_PUBLIC_KEY");

        //封装请求头参数
        RSA rsa = new RSA(null, spk);
        //对用户信息进行加密传输,暂仅支持传输OA用户ID
        String encryptUserid = rsa.encryptBase64("1", CharsetUtil.CHARSET_UTF_8, KeyType.PublicKey);

        //调用ECOLOGY系统接口
        log.info("调用泛微接口数据：{},--appid:{},--token:{},--userid:{}，--spk：{}", JSONUtil.toJsonStr(map),weaverConfig.getAppId(),token,encryptUserid,spk);
        HttpResponse execute = HttpRequest.post(weaverConfig.getHost() + apiPath)
                .header("appid", weaverConfig.getAppId())
                .header("token", token)
                .header("userid", encryptUserid)
                .contentType("application/x-www-form-urlencoded")
                .form(map)
                .execute();
        String data = execute.body();
        log.info("调用泛微接口返回：{}", data);
        return JSONUtil.parseObj(data);
    }


    /**
     * 第二步：
     *
     * 通过第一步中注册系统返回信息进行获取token信息
     */
    private Map<String, Object> getToken() {
        // 从系统缓存或者数据库中获取ECOLOGY系统公钥和Secret信息
        String secret = redisService.get("SERVER_SECRET");
        String spk = redisService.get("SERVER_PUBLIC_KEY");

        // 如果为空,说明还未进行注册,调用注册接口进行注册认证与数据更新
        if (Objects.isNull(secret) || Objects.isNull(spk)) {
            register();
            // 重新获取最新ECOLOGY系统公钥和Secret信息
            secret = redisService.get("SERVER_SECRET");
            spk = redisService.get("SERVER_PUBLIC_KEY");
        }

        // 公钥加密,所以RSA对象私钥为null
        RSA rsa = new RSA(null, spk);
        //对秘钥进行加密传输，防止篡改数据
        String encryptSecret = rsa.encryptBase64(secret, CharsetUtil.CHARSET_UTF_8, KeyType.PublicKey);

        //调用ECOLOGY系统接口进行注册
        String data = HttpRequest.post(weaverConfig.getHost() + "/api/ec/dev/auth/applytoken")
                .header("appid", weaverConfig.getAppId())
                .header("secret", encryptSecret)
                .header("time", "3600")
                .execute().body();

        log.info("泛微获取token接口----》getToken()：" + data);
        Map<String, Object> datas = JSONUtil.parseObj(data);

        //ECOLOGY返回的token
        redisService.set("SERVER_TOKEN", StrUtil.nullToEmpty((String) datas.get("token")), time);
        return datas;
    }
    /**
     * 泛微流程注册第一步：
     * 调用ecology注册接口,根据appid进行注册,将返回服务端公钥和Secret信息
     */
    private void register(){
        //获取当前系统RSA加密的公钥
        RSA rsa = new RSA();
        String publicKey = rsa.getPublicKeyBase64();
        String privateKey = rsa.getPrivateKeyBase64();

//        // 客户端RSA私钥
//        redisService.set("LOCAL_PRIVATE_KEY", privateKey, time);
//        // 客户端RSA公钥
//        redisService.set("LOCAL_PUBLIC_KEY", publicKey, time);

        //调用ECOLOGY系统接口进行注册
        String body = HttpRequest.post(weaverConfig.getHost() + "/api/ec/dev/auth/regist")
                .header("appid", weaverConfig.getAppId())
                .header("cpk", publicKey)
                .timeout(2000)
                .execute().body();
        log.info("register >>> {}", body);
        Map<String,Object> datas = JSONUtil.parseObj(body);

        //ECOLOGY返回的系统公钥
        redisService.set("SERVER_PUBLIC_KEY", StrUtil.nullToEmpty((String) datas.get("spk")), time);
        //ECOLOGY返回的系统密钥
        redisService.set("SERVER_SECRET", StrUtil.nullToEmpty((String) datas.get("secrit")), time);
    }


    public List<Map<String, Object>> buildRequestBody(Object obj) {
        if (ObjectUtils.isEmpty(obj)) {
            return null;
        }
        Class<?> aClass = obj.getClass();
        Field[] fields = aClass.getDeclaredFields();
        List<Map<String, Object>> res = new ArrayList<>();
        for (Field field : fields) {
            field.setAccessible(true);
            Map<String,Object> map = new HashMap<>();
            String name = field.getName();
            map.put("fieldName",name);
            try {
                map.put("fieldValue",field.get(obj));
            } catch (IllegalAccessException e) {
                map.put("fieldValue","");
                e.printStackTrace();
            }
            res.add(map);
        }
        return res;
    }




}


//------------------------------
 <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.27</version>
        </dependency>



         <dependency>
      <groupId>com.google.guava</groupId>
      <artifactId>guava</artifactId>
    </dependency>


    ---shiyong
    List<List<Long>> lists = Lists.partition(ids, 500);